package com.admin.filter;

import com.admin.vo.TokenInfo;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
@Slf4j
public class CookieTokenFilter extends ZuulFilter
{
  @Autowired
  private RestTemplate restTemplate;

  @Override
  public String filterType() {
    return "pre";
  }

  @Override
  public int filterOrder() {
    return 2;
  }

  @Override
  public boolean shouldFilter() {
    return true;
  }

  @Override
  public Object run() throws ZuulException {
    RequestContext currentContext = RequestContext.getCurrentContext();
    HttpServletRequest request = currentContext.getRequest();
    HttpServletResponse response = currentContext.getResponse();

    String accessToken=getCookie("access_token");
    if(StringUtils.isNotBlank(accessToken)){
      currentContext.addZuulRequestHeader("Authorization","bearer "+accessToken);
    }
    else{
      String refreshToken=getCookie("refresh_token");
      if(StringUtils.isNotBlank(refreshToken)){
        String oauthServiceUrl="http://gateway.test.com:8091/token/oauth/token";
        HttpHeaders httpHeaders=new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        httpHeaders.setBasicAuth("admin","123456");

        MultiValueMap<String,String> params=new LinkedMultiValueMap<String,String>();
        params.add("grant_type","refresh_token");
        params.add("refresh_token",refreshToken);

        HttpEntity<MultiValueMap> httpEntity=new HttpEntity<MultiValueMap>(params,httpHeaders);
        try{

          ResponseEntity<TokenInfo> newtoken = restTemplate.exchange(oauthServiceUrl, HttpMethod.POST, httpEntity, TokenInfo.class);
          log.info("token:{}",newtoken.getBody());
          currentContext.addZuulRequestHeader("Authorization","bearer "+newtoken);
          Cookie access_cookie=new Cookie("access_token",newtoken.getBody().getAccess_token());
          access_cookie.setMaxAge(newtoken.getBody().getExpires_in().intValue());
          access_cookie.setPath("/");
          access_cookie.setDomain("test.com");
          response.addCookie(access_cookie);
          Cookie refresh_token_cookie=new Cookie("refresh_token",newtoken.getBody().getRefresh_token());
          refresh_token_cookie.setMaxAge(2592000);
          refresh_token_cookie.setPath("/");
          refresh_token_cookie.setDomain("test.com");
          response.addCookie(refresh_token_cookie);
        }catch(Exception ex){
          currentContext.setSendZuulResponse(false);
          currentContext.setResponseBody("{\"message\":\"refresh fail\"}");
          currentContext.setResponseStatusCode(500);
          currentContext.getResponse().setContentType("application/json");
        }

      }
      else{
        currentContext.setSendZuulResponse(false);
        currentContext.setResponseBody("{\"message\":\"refresh fail\"}");
        currentContext.setResponseStatusCode(500);
        currentContext.getResponse().setContentType("application/json");

      }
    }

    return null;
  }

  private String getCookie(String name) {
    RequestContext requestContext=RequestContext.getCurrentContext();
    HttpServletRequest request = requestContext.getRequest();
    Cookie[] cookies = request.getCookies();
    for (Cookie cookie : cookies) {
      if(StringUtils.equals(name,cookie.getName())){
        return cookie.getName();
      }
    }
    return null;
  }
}
